package com.fsnbigdata.service.impl;
import com.fsnbigdata.domain.dto.NamingPair;
import com.fsnbigdata.service.api.ParkService;

import com.fsnbigdata.util.ObjectNull;
import com.querydsl.core.types.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.roo.addon.layers.service.annotations.RooServiceImpl;
import com.fsnbigdata.domain.Park;
import com.fsnbigdata.domain.ParkDistrict;
import com.fsnbigdata.repository.ParkRepository;
import com.fsnbigdata.service.api.ParkDistrictService;
import io.springlets.data.domain.GlobalSearch;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;

/**
 * = ParkServiceImpl
 *
 * TODO Auto-generated class documentation
 *
 */
@RooServiceImpl(service = ParkService.class)
@Service
@Transactional(readOnly = true)
public class ParkServiceImpl implements ParkService {

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private ParkDistrictService parkDistrictService;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private ParkRepository parkRepository;

    /**
     * TODO Auto-generated constructor documentation
     *
     * @param parkRepository
     * @param parkDistrictService
     */
    @Autowired
    public ParkServiceImpl(ParkRepository parkRepository, @Lazy ParkDistrictService parkDistrictService) {
        setParkRepository(parkRepository);
        setParkDistrictService(parkDistrictService);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return ParkRepository
     */
    public ParkRepository getParkRepository() {
        return parkRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param parkRepository
     */
    public void setParkRepository(ParkRepository parkRepository) {
        this.parkRepository = parkRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return ParkDistrictService
     */
    public ParkDistrictService getParkDistrictService() {
        return parkDistrictService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param parkDistrictService
     */
    public void setParkDistrictService(ParkDistrictService parkDistrictService) {
        this.parkDistrictService = parkDistrictService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param park
     * @param districtsToAdd
     * @return Park
     */
    @Transactional
    public Park addToDistricts(Park park, Iterable<ParkDistrict> districtsToAdd) {
        park.addToDistricts(districtsToAdd);
        return getParkRepository().save(park);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param park
     * @param districtsToRemove
     * @return Park
     */
    @Transactional
    public Park removeFromDistricts(Park park, Iterable<Long> districtsToRemove) {
        List<ParkDistrict> districts = getParkDistrictService().findAll(districtsToRemove);
        park.removeFromDistricts(districts);
        return getParkRepository().save(park);
    }

    @Override
    public List<NamingPair> findAllByInitial(String initial) {
        return getParkRepository().findALlByInitial(initial);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param park
     */
    @Transactional
    public void delete(Park park) {
        // Clear bidirectional one-to-many parent relationship with ParkDistrict
        for (ParkDistrict item : park.getDistricts()) {
            item.setPark(null);
        }
        getParkRepository().delete(park);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param entities
     * @return List
     */
    @Transactional
    public List<Park> save(Iterable<Park> entities) {
        return getParkRepository().save(entities);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     */
    @Transactional
    public void delete(Iterable<Long> ids) {
        List<Park> toDelete = getParkRepository().findAll(ids);
        getParkRepository().deleteInBatch(toDelete);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param entity
     * @return Park
     */
    @Transactional
    public Park save(Park entity) {
        return getParkRepository().save(entity);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param id
     * @return Park
     */
    public Park findOne(Long id) {
        return getParkRepository().findOne(id);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param id
     * @return Park
     */
    public Park findOneForUpdate(Long id) {
        return getParkRepository().findOneDetached(id);
    }

    @Override
    public Page<Park> search(Predicate predicate, Pageable pageable) {
        return getParkRepository().findAll(predicate, pageable);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     * @return List
     */
    public List<Park> findAll(Iterable<Long> ids) {
        return getParkRepository().findAll(ids);
    }

    /**
     * 前台页面加载数据
     * @param pageable
     * @return
     */
    public Page<Park> findAll(Pageable pageable) {
        return getParkRepository().findAll(pageable);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return List
     */
    public List<Park> findAll() {
        return getParkRepository().findAll();
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Long
     */
    public long count() {
        return getParkRepository().count();
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    public Page<Park> findAll(GlobalSearch globalSearch, Pageable pageable) {
        return getParkRepository().findAll(globalSearch, pageable, null);
    }

    @Override
    public Page<Park> findAll(GlobalSearch globalSearch, Pageable pageable, String creator) {
        return getParkRepository().findAll(globalSearch, pageable, creator);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    public Page<Park> findAllByIdsIn(List<Long> ids, GlobalSearch globalSearch, Pageable pageable) {
        return getParkRepository().findAllByIdsIn(ids, globalSearch, pageable);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Class
     */
    public Class<Park> getEntityType() {
        return Park.class;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Class
     */
    public Class<Long> getIdType() {
        return Long.class;
    }

    @Override
    public List<List<Park>> findAllByType() {
        List<List<Park>> list = new ArrayList <>();
        for (Integer i=0;i<4;i++){
            List<Park> park = getParkRepository().findAllByType(i);
            if(park!=null&&park.size()>4){
                list.add(park.subList( 0,4 )) ;
            }else {
                list.add(park);
            }
        }
        return list;
    }

    @Override
    public List<Park> findAllByType(Integer type) {
        return getParkRepository().findAllByType(type);
    }

    @Override
    public List findByPageAndSize(String type, String city, String name, Pageable pageable) {
        class  NewPark{
            private String id;
            private String name;
            private String creator;
            private String description;
            private String image;
            private String initial;
            private String version;
            private String type;

            public String getId() {
                return id;
            }

            public void setId(String id) {
                this.id = id;
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public String getCreator() {
                return creator;
            }

            public void setCreator(String creator) {
                this.creator = creator;
            }

            public String getDescription() {
                return description;
            }

            public void setDescription(String description) {
                this.description = description;
            }

            public String getImage() {
                return image;
            }

            public void setImage(String image) {
                this.image = image;
            }

            public String getInitial() {
                return initial;
            }

            public void setInitial(String initial) {
                this.initial = initial;
            }

            public String getVersion() {
                return version;
            }

            public void setVersion(String version) {
                this.version = version;
            }

            public String getType() {
                return type;
            }

            public void setType(String type) {
                this.type = type;
            }
        }
        List<Long> parkIds=new ArrayList<>();
        //获取动植物园id集合
        if (city!=null&&!"".equals(city)){
           parkIds =parkDistrictService.getIdsByCity(city);
        }
        String sign = parkIds.size()>0?parkIds.get(0)+"":null;
        parkIds = parkIds.size()>0?parkIds:null;
        List<Object> parkList = parkRepository.findAllByIdsAndTypeAndName(type,name,sign,parkIds,pageable);
        List list = new ArrayList();
        List<NewPark> parks = new ArrayList<>();
        for(Object obj:parkList){
            Object[] objects = (Object[]) obj;
            NewPark newPark =new NewPark();
            newPark.setId(""+objects[0]);
            newPark.setName( ObjectNull.takeOutNull(objects[1]));
            newPark.setCreator(ObjectNull.takeOutNull(objects[2]));
            newPark.setInitial(ObjectNull.takeOutNull(objects[3]));
            newPark.setImage(ObjectNull.takeOutNull(objects[4]));
            newPark.setDescription(ObjectNull.takeOutNull(objects[5]));
            newPark.setVersion(ObjectNull.takeOutNull(objects[6]));
            newPark.setType(ObjectNull.takeOutNull(objects[7]));
            parks.add(newPark);
        }
        list.add( parkRepository.CountByKey(type,name,sign,parkIds) );
        list.add( parks );
        return list;
    }
}
